﻿using HelperFromTheSkeleton.APICore.Filters;
using HelperFromTheSkeleton.Common;
using HelperFromTheSkeleton.HttpManage;
using HelperFromTheSkeleton.JwtHelper;
using HelperFromTheSkeleton.Model.APICoreModels;
using Materal.Logger;
using Materal.TTA.Common.Model;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace HelperFromTheSkeleton.APICore
{
    /// <summary>
    /// WebApplicationBuilder帮助类
    /// </summary>
    public static class WebApplicationBuilderHelper
    {
        /// <summary>
        /// 应用名
        /// </summary>
        private static string? _applicationName;

        /// <summary>
        /// 应用编码
        /// </summary>
        private static string? _applicationCode;

        public static WebApplicationBuilder CreatBuilder(CreatBuilderModel model)
        {
            CreatBuilderModel model2 = model;
            WebApplicationBuilder webApplicationBuilder = WebApplication.CreateBuilder(model2.Args);
            _applicationName = model2.ApiName;
            _applicationCode = model2.ApiCode;
            string basePath = AppContext.BaseDirectory;
            webApplicationBuilder.Services.AddControllers(delegate (MvcOptions options)
            {
                options.Filters.Add(new APICoreExceptionFilter());
                options.Filters.Add(new APICoreActionFilter());
            });
            webApplicationBuilder.Services.AddEndpointsApiExplorer();
            webApplicationBuilder.Services.AddCors(delegate (CorsOptions policy)
            {
                policy.AddPolicy("CorsPolicy", delegate (CorsPolicyBuilder opt)
                {
                    opt.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()
                        .WithExposedHeaders("X-Pagination");
                });
            });
            if (!model2.isSmallHump)
            {
                webApplicationBuilder.Services.AddMvc().AddJsonOptions(delegate (JsonOptions m)
                {
                    m.JsonSerializerOptions.PropertyNamingPolicy = null;
                });
            }

            OpenApiSecurityScheme securityScheme = new OpenApiSecurityScheme
            {
                Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.Http,
                Scheme = "bearer",
                BearerFormat = "JWT"
            };
            OpenApiSecurityRequirement securityRequirement = new OpenApiSecurityRequirement {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "bearerAuth"
                    }
                },
                Array.Empty<string>()
            } };
            webApplicationBuilder.Services.AddLogging();
            webApplicationBuilder.Services.AddSwaggerGen(delegate (SwaggerGenOptions m)
            {
                m.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = (model2.ApiName ?? "")
                });
                string[] aPIXmlPath = model2.APIXmlPath;
                foreach (string path in aPIXmlPath)
                {
                    m.IncludeXmlComments(Path.Combine(basePath, path), includeControllerXmlComments: true);
                }

                m.AddSecurityDefinition("bearerAuth", securityScheme);
                m.AddSecurityRequirement(securityRequirement);
            });
            webApplicationBuilder.Services.AddAuthentication("Bearer").AddJwtBearer(delegate (JwtBearerOptions o)
            {
                o.TokenValidationParameters = Config.TokenValidationParametersParameters;
            });
            webApplicationBuilder.Services.AddScoped((IServiceProvider n) => new JwtManage(Config.TokenValidationParametersParameters, 12));
            webApplicationBuilder.Services.AddSingleton<IHttpService>(m => new HttpService());
            return webApplicationBuilder;
        }

        public static WebApplication WebAppBuild<T>(this WebApplicationBuilder builder, T config) where T : Config
        {
            WebApplication webApplication = builder.Build();
            config.Init(webApplication.Services, _applicationName ?? "", _applicationCode ?? "");
            IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("MateralLogger.json", optional: true, reloadOnChange: true).Build();
            LoggerManager.CustomConfig.Add("ApplicationName", _applicationName ?? "");
            LoggerManager.CustomConfig.Add("LogDBConnectionString", new SqlServerConfigModel
            {
                Address = (Config.LogDBConnectionConfig?.Address ?? ""),
                Port = (Config.LogDBConnectionConfig?.Port ?? 1433).ToString(),
                Name = (Config.LogDBConnectionConfig?.DBName ?? ""),
                UserID = (Config.LogDBConnectionConfig?.User ?? ""),
                Password = (Config.LogDBConnectionConfig?.Password ?? ""),
                TrustServerCertificate = (Config.LogDBConnectionConfig?.TrustServerCertificate ?? true)
            }.ConnectionString);
            webApplication.UseMateralLogger(null, configuration);
            webApplication.UseSwagger();
            webApplication.UseSwaggerUI();
            webApplication.UseCors("CorsPolicy");
            webApplication.UseHttpsRedirection();
            webApplication.UseAuthentication();
            webApplication.UseAuthorization();
            webApplication.MapControllers();
            return webApplication;
        }
    }
}